import fs from 'node:fs'
import path from 'node:path'

import { MultipartFile } from '@fastify/multipart'

import dayjs from 'dayjs'
import { env } from "~/global/env";

enum Type {
	IMAGE = 'image',
	TXT = 'doc',
	MUSIC = 'music',
	VIDEO = 'video',
	OTHER = 'other',
}

export function getFileType(extName: string) {
	const documents = 'txt doc pdf ppt pps xlsx xls docx'
	const music = 'mp3 wav wma mpa ram ra aac aif m4a'
	const video = 'avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg'
	const image
		= 'bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg'
	if (image.includes(extName))
		return Type.IMAGE

	if (documents.includes(extName))
		return Type.TXT

	if (music.includes(extName))
		return Type.MUSIC

	if (video.includes(extName))
		return Type.VIDEO

	return Type.OTHER
}

export function getName(fileName: string) {
	if (fileName.includes('.'))
		return fileName.split('.')[0]

	return fileName
}

export function getExtname(fileName: string) {
	return path.extname(fileName).replace('.', '')
}

export function getSize(bytes: number, decimals = 2) {
	if (bytes === 0)
		return '0 Bytes'

	const k = 1024
	const dm = decimals < 0 ? 0 : decimals
	const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']

	const i = Math.floor(Math.log(bytes) / Math.log(k))

	return `${Number.parseFloat((bytes / k ** i).toFixed(dm))} ${sizes[i]}`
}

export function fileRename(fileName: string) {
	const name = fileName.split('.')[0]
	const extName = path.extname(fileName)
	const time = dayjs().format('YYYYMMDDHHmmSSS')
	return `${name}-${time}${extName}`
}

export function getOssDirPath(currentDate: string, type: string, name: string): string {
	return `/${currentDate}/${type}/${name}`
}

export function getDirPath(currentDate: string, type: string): string {
	return path.join(__dirname, '../../', 'public/upload/', `${currentDate}/`, `${type}/`)
}

export function getFilePath(name: string, currentDate: string, type: string) {
	return `${getDirPath(currentDate, type)}${name}`
}

export function saveLocalFile(buffer: Buffer, name: string, currentDate: string, type: string): Promise<string> {
	return new Promise(async (resolve, reject) => {
		const dirPath = getDirPath(currentDate, type)
		try {
			// 判断是否有该文件夹
			await fs.promises.stat(dirPath)
		} catch (error) {
			// 没有该文件夹就创建
			await fs.promises.mkdir(dirPath, { recursive: true })
		}
		// 文件路径
		const localFilePath = getFilePath(name, currentDate, type)
		const writeStream = fs.createWriteStream(localFilePath)
		writeStream.write(buffer, (error) => {
			if (error) {
				reject(error)
			}
			resolve(localFilePath)
		})
	})
}

export function saveFile(file: MultipartFile, name: string) {
	return new Promise(async (resolve, reject) => {
		const filePath = path.join(__dirname, '../../', 'public/upload', name)
		const writeStream = fs.createWriteStream(filePath)
		const buffer = await file.toBuffer()
		writeStream.write(buffer, (error) => {
			if (error) {
				reject(error)
			}
			resolve(filePath)
		})
	})
}

export async function deleteFile(name: string) {
	fs.unlink(path.join(__dirname, '../../', 'public', name), () => {
		// console.log(error);
	})
}

export function getFileFullPath(path: string): string {
	return `${env("STATIC_PREFIX")}${path}`
}
